﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IrisGenerator.Common.Core;
using IrisGenerator.Common.Core.Rules;
using IrisGenerator.Framework.RuleEngine;
using IrisGenerator.Framework.Messaging;
using IrisGenerator.Framework.Events;


namespace IrisGenerator.Common.DataTypes.Rules
{
    public class MetatypeEquivalencesRule : RuleBase<MetatypeEquivalences>, IDbBindableObjectRules
    {

        #region ctor

        public MetatypeEquivalencesRule(MetatypeEquivalences obj)
            : base(obj)
        {
            //_innerMetatype.Inserted += new EventHandler<BaseEventArgs<Metatype>>(_innerMetatype_Inserted);
            this.LinkedObject.Deleting += new EventHandler<BaseEventArgs<MetatypeEquivalences>>(LinkedObject_Deleting);
        }

        #endregion

        #region Properties' Rules

        private bool MetIdIsValid(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            
            if (this.LinkedObject.MetId == null || this.LinkedObject.TarId.Equals(Guid.Empty))
            {
                if (returnValue == null)
                    returnValue = new RuleErrorCollection();
                returnValue.Add(new RuleError("Metatype ID", RuleErrorType.PropertyRule, "An Identifier is mandatory"));
                result = false;
            }

            return result;
        }

        private bool TarIdIsValid(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            if (this.LinkedObject.TarId == null || this.LinkedObject.TarId.Equals(Guid.Empty))
            {
                if (returnValue == null)
                    returnValue = new RuleErrorCollection();
                returnValue.Add(new RuleError("Target ID", RuleErrorType.PropertyRule, "An Identifier is mandatory"));
                result = false;
            }

            return result;
        }

        private bool MetEquTypeIsValid(ref RuleErrorCollection returnValue)
        {
            return true;
        }

        private bool MetEquSpecifyLengthIsValid(ref RuleErrorCollection returnValue)
        {
            return true;

        }

        private bool MetEquSpecifyPrecisionIsValid(ref RuleErrorCollection returnValue)
        {
            return true;
        }

        #endregion

        #region Persistancy Rules

        #region IDbBindableObjectRules

        public bool CanInsert(ref RuleErrorCollection returnValue)
        {
            bool result = true;
            result = result & MetIdIsValid(ref returnValue);
            result = result & TarIdIsValid(ref returnValue);
            result = result & MetEquTypeIsValid(ref returnValue);
            result = result & MetEquSpecifyPrecisionIsValid(ref returnValue);
            result = result & MetEquSpecifyLengthIsValid(ref returnValue);
            
            if (PrimaryKeyExists())
            {
                if (returnValue == null)
                    returnValue = new RuleErrorCollection();

                returnValue.Add(new RuleError("Metatype Object Conflict", RuleErrorType.BusinessRule, "The id already exists"));
                result = false;
            }

            return (result);
        }

        private bool PrimaryKeyExists()
        {
            var tmp = MetatypeEquivalences.Load(this.LinkedObject.TarId,this.LinkedObject.MetId);
            return (tmp != null);
        }

        public bool CanUpdate(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            result = result & MetIdIsValid(ref returnValue);
            result = result & TarIdIsValid(ref returnValue);
            result = result & MetEquTypeIsValid(ref returnValue);
            result = result & MetEquSpecifyPrecisionIsValid(ref returnValue);
            result = result & MetEquSpecifyLengthIsValid(ref returnValue);

            return result;
        }

        public bool CanDelete(ref RuleErrorCollection returnValue)
        {
            bool result = false;

            result = MetIdIsValid(ref returnValue) && TarIdIsValid(ref returnValue);
            //result = result & ;

            return result;
        }

        #endregion

        #region Events Handling

        private void LinkedObject_Deleting(object sender, BaseEventArgs<MetatypeEquivalences> e)
        {
            if (e.FireMessage)
            {
                Message message = new Message("Are you sure you want to delete the metatype equivalence" + e.Argument.Metatype.MetCode + "?"
                    + Environment.NewLine + "This action will delete all linked elements.", "Metatype Equivalence deletion",
                    MessageButtons.YesNo, MessageIcon.Question, MessageDefaultButton.Button2);

                MessageResults result = OnMessageSend(new MessageEventArgs<MetatypeEquivalences>(e.Argument, message));
                if (result != MessageResults.Yes)
                {
                    e.Cancel = true;
                    return;
                }
            }
        }

        /// <summary>
        /// Occures when a metatype is inserted. Adds the adequate rows to the 
        /// MetaType Equivalences.
        /// </summary>
        /// <param name="sender">The object that fires the event</param>
        /// <param name="e">The metatype base event args.</param>
        private void LinkedObject_Inserted(object sender, BaseEventArgs<Metatype> e)
        {
            //AddMissingEquivalences(e.Argument);
        }

        #endregion

        #endregion

    }
}

